#include <GL/gl.h>
#include <iostream>

#include "combinedObject.h"
#include "defines/axes.h"
#include "defines/octreeType.h"

CombinedObject::CombinedObject(int _id) : Object(_id){
}

CombinedObject::CombinedObject(int _operation, const Color &_c, int _id)
    : Object(_c, _id, _operation, false){
}

CombinedObject::CombinedObject(int _operation, std::vector<Object *> _objects, int _id)
    : Object(_id, _operation, false), objects(_objects){
}

CombinedObject::CombinedObject(int _operation, std::vector<Object *> _objects, const Color &_c, int _id)
    : Object(_c, _id, _operation, false), objects(_objects){
}

CombinedObject::~CombinedObject(){
    unsigned int size = objects.size();
    for(unsigned int i = 0; i < size; i++){
        Object *obj = objects.back();
        objects.pop_back();
        delete obj;
    }
}

void CombinedObject::changeOperation(int _op){
    type = _op;
}

void CombinedObject::deleteObject(Object *_o){
    int size = objects.size();
    for (int i = size; i > 0; i--){
        if ( objects.at(i - 1) == _o ){
            objects.erase(objects.begin() + i - 1);
        }
    }
}

unsigned int CombinedObject::getObjectsSize() const{
    return objects.size();
}

Object *CombinedObject::getObject(unsigned int _i) const{
    return objects.at(_i);
}

void CombinedObject::addObject(Object *_obj){
    objects.push_back(_obj);
}

void CombinedObject::draw(bool _wireframe, bool _useParentColor, const Color & _parentColor) const{
//    /** tem que fazer uma bouding box qando estiver selecionado */



    if(selected){
        Vector3D min, max;
        getMinMax(&min.x, &max.x, X_AXIS);
        getMinMax(&min.y, &max.y, Y_AXIS);
        getMinMax(&min.z, &max.z, Z_AXIS);
        drawBox(true, min, max);
    }


    glPushMatrix();
	glRotated(rotationX * 90, 1.0, 0.0, 0.0);
	glRotated(rotationY * 90, 0.0, 1.0, 0.0);
	glRotated(rotationZ * 90, 0.0, 0.0, 1.0);

//    std::cout <<"\t\tA combinação " << id << " tem " <<objects.size() << " objetos: (" <<std::endl;
    for(unsigned int i = 0; i < objects.size(); i++){

        Object *obj = objects.at(i);
//        std::cout <<"\t\t\t" << obj->getId() <<std::endl;
        if(_useParentColor){
            obj->draw(_wireframe, _useParentColor, _parentColor);
        }else{
            obj->draw(_wireframe, true, color);
        }
    }

    glPopMatrix();

//    std::cout << "\t\t)" <<std::endl;
}

void CombinedObject::getMinMax(double *_min, double *_max, unsigned int _axis) const{
    switch(type){
        case UNION:{
            objects.at(0)->getMinMax(_min, _max, _axis);

            for(unsigned int i = 1; i < objects.size(); i++){
                double min, max;
                objects.at(i)->getMinMax(&min, &max, _axis);
                if(min < *_min) *_min = min;
                if(max > *_max) *_max = max;
            }
            break;
        }
        case INTERSECTION:{
            objects.at(0)->getMinMax(_min, _max, _axis);
            for(unsigned int i = 1; i < objects.size(); i++){
                double min, max;
                objects.at(i)->getMinMax(&min, &max, _axis);
                if(min > *_min) *_min = min;
                if(max < *_max) *_max = max;
            }
            break;
        }
        case DIFFERENCE:{
            objects.at(0)->getMinMax(_min, _max, _axis);
            break;
        }
    }


}
